From: Roger Pau Monné Date: Mon, 10 Apr 2017 15:32:01 +0000 (+0200) Subject: x86/atomic: fix cmpxchg16b inline assembly to work with clang X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~2240 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=17cd6621688bce9972d9242611114fd7aba44c31;p=xen.git x86/atomic: fix cmpxchg16b inline assembly to work with clang clang doesn't understand the "=A" register constrain when used with 64bits assembly and spits out an internal error: fatal error: error in backend: Cannot select: 0x7f9fb89c9390: i64 = build_pair 0x7f9fb89c92b0, 0x7f9fb89c9320 0x7f9fb89c92b0: i32,ch,glue = CopyFromReg 0x7f9fb89c9240, Register:i32 %EAX, 0x7f9fb89c9240:1 0x7f9fb89c8c20: i32 = Register %EAX 0x7f9fb89c9240: ch,glue = inlineasm 0x7f9fb89c90f0, TargetExternalSymbol:i64'lock; cmpxchg16b $1', MDNode:ch<0x7f9fb8476c38>, TargetConstant:i64<25>, TargetConstant:i32<18>, Register:i32 %EAX, Register:i32 %EDX, TargetConstant:i32<196622>, 0x7f9fb89c87c0, TargetConstant:i32<9>, Register:i64 %RCX, TargetConstant:i32<9>, Register:i64 %RBX, TargetConstant:i32<9>, Register:i64 %RDX, TargetConstant:i32<9>, Register:i64 %RAX, TargetConstant:i32<196622>, 0x7f9fb89c87c0, TargetConstant:i32<12>, Register:i32 %EFLAGS, 0x7f9fb89c90f0:1 0x7f9fb89c8a60: i64 = TargetExternalSymbol'lock; cmpxchg16b $1' 0x7f9fb89c8b40: i64 = TargetConstant<25> 0x7f9fb89c8bb0: i32 = TargetConstant<18> 0x7f9fb89c8c20: i32 = Register %EAX 0x7f9fb89c8c90: i32 = Register %EDX 0x7f9fb89c8d00: i32 = TargetConstant<196622> 0x7f9fb89c87c0: i64,ch = load 0x7f9fb9053da0, FrameIndex:i64<1>, undef:i64 0x7f9fb9053a90: i64 = FrameIndex<1> 0x7f9fb9053e80: i64 = undef 0x7f9fb89c8e50: i32 = TargetConstant<9> 0x7f9fb89c8d70: i64 = Register %RCX 0x7f9fb89c8e50: i32 = TargetConstant<9> 0x7f9fb89c8ec0: i64 = Register %RBX 0x7f9fb89c8e50: i32 = TargetConstant<9> 0x7f9fb89c8fa0: i64 = Register %RDX 0x7f9fb89c8e50: i32 = TargetConstant<9> 0x7f9fb89c9080: i64 = Register %RAX [...] Fix this by specifying "rdx:rax" manually using the "d" and "a" constraints. Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich --- diff --git a/xen/include/asm-x86/x86_64/system.h b/xen/include/asm-x86/x86_64/system.h index 7026c05a25..88beae130b 100644 --- a/xen/include/asm-x86/x86_64/system.h +++ b/xen/include/asm-x86/x86_64/system.h @@ -14,20 +14,21 @@ */ static always_inline __uint128_t __cmpxchg16b( - volatile void *ptr, const __uint128_t *old, const __uint128_t *new) + volatile void *ptr, const __uint128_t *oldp, const __uint128_t *newp) { - __uint128_t prev; - uint64_t new_high = *new >> 64; - uint64_t new_low = *new; + union { + struct { uint64_t lo, hi; }; + __uint128_t raw; + } new = { .raw = *newp }, old = { .raw = *oldp }, prev; ASSERT(cpu_has_cx16); - asm volatile ( "lock; cmpxchg16b %1" - : "=A" (prev), "+m" (*__xg(ptr)) - : "c" (new_high), "b" (new_low), - "0" (*old) ); + /* Don't use "=A" here - clang can't deal with that. */ + asm volatile ( "lock; cmpxchg16b %2" + : "=d" (prev.hi), "=a" (prev.lo), "+m" (*__xg(ptr)) + : "c" (new.hi), "b" (new.lo), "0" (old.hi), "1" (old.lo) ); - return prev; + return prev.raw; } #define cmpxchg16b(ptr, o, n) ({ \